# coding: utf8


import numpy as np
import pandas as pd
import random


class Demo:

    def __init__(self):
        self.df1 = pd.DataFrame(
            data={'A': [1, 2, 3],
                  'B': [10, 20, 30],
                  'C': [1.1, 2.2, 3.3]},
            index=[1, 2, 3]
            )
        self.df2 = pd.DataFrame(
            data={'B': [2, 4, 6],
                  'C': [20, 40, 60],
                  'D': [-1, -2, -3]},
            index=[2, 3, 4]
        )
        self.sr1 = pd.Series([1, 3, 5], index=[1, 2, 4])
        self.sr2 = pd.Series([2, 4, 6], index=[1, 3, 4])
        # print(
        #     ""
        #     " >>> df1\n"
        #     f"{self.df1}\n"
        #     f" >>> df2\n"
        #     f"{self.df2}\n"
        #     f" >>> sr1\n"
        #     f"{self.sr1}\n"
        #     f" >>> sr2\n"
        #     f"{self.sr2}"
        # )

    def op_df2df(self):
        df1 = pd.DataFrame(
            data={'A': [1, 1, 1],
                  'B': [2, 2, 2],
                  'C': [3, 3, 3]},
            index=[1, 2, 3]
            )
        df2 = pd.DataFrame(
            data={'B': [10, 10, 10],
                  'C': [20, 20, 20],
                  'D': [0, 0, 0]},
            index=[2, 3, 4]
        )

        print(
            " >>> df1\n"
            f"{df1}\n"
            f" >>> df2\n"
            f"{df2}\n"

            f"{'-'*80}"
            "# 使用运算符进行运算\n"
            "# 不能对齐的位置填充为NaN\n"
            " >>> df1 + df2\n"
            f"{df1 + df2}\n"

            "# 使用运算方法进行运算，可以设置填充值\n"
            "  填充值只针对两个数据集中有一个缺失的位置\n"
            " >>> df1.add(df2, fill_value=100)\n"
            f"{df1.add(df2, fill_value=100)}\n"
        )

    def op_df2sr(self):
        df = pd.DataFrame(
            data={'A': [1, 1, 1],
                  'B': [2, 2, 2],
                  'C': [3, 3, 3]},
            index=[1, 2, 3]
            )
        sr1 = pd.Series([100, 200, 300], index=[2, 3, 4])
        sr2 = pd.Series([100, 200, 300], index=['B', 'C', 'D'])

        print(
            " >>> df\n"
            f"{df}\n"
            f" >>> sr1\n"
            f"{sr1}\n"
            f" >>> sr2\n"
            f"{sr2}\n"

            f"# 使用运算符进行运算，Series只能作为加数，其索引与列标签进行对齐匹配\n"
            f"# 没有列名可以匹配时，保留Series的索引标签作为列名，所有值置为NaN\n"
            f" >>> df + sr1\n"
            f"{df + sr1}\n"
            
            f"# 存在列名与Series的索引标签可以匹配，"
            f"# Series作为行向量，依次与DataFrame各行进行匹配运算\n"
            f" >>> df + sr2\n"
            f"{df + sr2}\n"
            
            f"# 使用运算方法，可以设置沿不同轴向对齐\n"
            f"# 设置axis=0，DataFrame使用行索引与Series的索引对齐\n"
            f" >>> df.add(sr1, axis=0)\n"
            f"{df.add(sr1, axis=0)}\n"

            f" >>> df.add(sr1, axis=0).fillna(1000)\n"
            f"{df.add(sr1, axis=0).fillna(1000)}\n"
        )
        return df, sr1, sr2

    def op_sr2sr(self):
        pass

    def op_ds2value(self):
        df = pd.DataFrame(
            data={'A': [1, 2, 3],
                  'B': ['apple', 'orange', 'banana'],
                  'C': [pd.Timestamp(2010, 1, j) for j in range(1, 4)]
                  }
        )
        df2 = self.df1

        print(
            f" >>> df\n"
            f"{df}\n"
            f" >>> df.info()\n"
            f"{df.info()}\n"
            
            "# 数据集与标量进行运算，类型需要全部可以类型兼容\n"
            "# 类型不兼容，则会触发异常：\n"
            " >>> df + 300\n"
            # f"{df + 100}\n"
            f"TypeError: Addition/subtraction of integers and integer-arrays with DatetimeArray is no longer supported.\n"
            f"Instead of adding/subtracting `n`, use `n * obj.freq`\n"
            
            "# 数据集与标量不能类型兼容时，可以采取分列运算方式\n"
            " >>> df['A'] = df['A'] + 100\n"
            " >>> df.A\n"
            f"{df['A']+100}\n"
            
            "# 类型兼容时，可以进行数据集与标量的运算\n"
            " >>> df2\n"
            f"{df2}\n"
            f" >>> df2 + 100\n"
            f"{df2 + 100}\n"
        )
        return
